# simulate serial send
# should be used with Eltima VSPD's paired com ports
import serial 
import logging
from logging.config import dictConfig
import yaml
import os
import time
from math import pi, cos


# 计算程序文件所在的实际目录，文件名和无扩展的文件名
real_path = os.path.realpath(__file__)
logging.info('real_path = {}'.format(real_path))
base_name = os.path.basename(real_path)
logging.info('base_name = {}'.format(base_name))
base_dir = os.path.dirname(real_path)
logging.info('base_dir = {}'.format(base_dir))
os.chdir(base_dir)
logging.info('change dir to base_dir = {}'.format(os.getcwd()))
program_name,_ext = os.path.splitext(base_name)
config_file = os.path.join(base_dir,program_name+'.yaml') #计算配置文件
logging.info('config_file = {}'.format(config_file))

import yaml
with open(config_file,'r',encoding='utf-8') as file:
    config = yaml.load(file,Loader=yaml.Loader)
logging.info(f'config={config}')
dictConfig(config['logging'])
logger = logging.getLogger()
logger.info('config:')
logger.info(config)

def main(main_config):
    with  serial.Serial(**main_config['serial'])  as ser:
        delay = main_config['delay'] 

        lower_limits = [10,20,30,40]
        upper_limits = [15,30,40,90]
        periods = [30,40,50,30]
        phases = [10,20,30,40] # degree

        while(True):  
            try:
                t = time.time()
                values = [l+(u-l)/2*cos(2*pi/T*t+p/180*pi) for l,u,T,p in zip(lower_limits,upper_limits,periods,phases)]
                b  = '{:05.2f} {:05.2f} {:05.2f} {:05.2f}\n'.format(*values).encode(encoding='ascii')
                logger.info(f'sending b={b}')
                ser.write(b)
                #logger.debug(f'in_waiting={ser.in_waiting}')
                #logger.debug(f'out_waiting={ser.out_waiting}')
                time.sleep(delay)
            except serial.SerialException as e:
                logger.exception(e)
                continue
            except KeyboardInterrupt:
                logger.info('KeyboardInterrupt')
                break
            except Exception as e:
                logger.exception('e')
                break

if __name__ == "__main__":
    try:
        main(config['main'])   
    except Exception as e:
        raise
    finally:
        input('press any key to exit')